package com.limh.readers.activity

import android.Manifest
import android.app.Activity
import android.app.AlertDialog
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.provider.Settings
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.util.Log

/**
 * Android 6.0 上权限分为**正常**和**危险**级别
 *
 *  * 正常级别权限：开发者仅仅需要在AndroidManifext.xml上声明，那么应用就会被允许拥有该权限，如：android.permission.INTERNET
 *  * 危险级别权限：开发者需要在AndroidManifext.xml上声明，并且在运行时进行申请，而且用户允许了，应用才会被允许拥有该权限，如：android.permission.WRITE_EXTERNAL_STORAGE
 *
 * 有米的以下权限需要在Android6.0上被允许，有米广告sdk才能正常工作，开发者需要在调用有米的任何代码之前，提前让用户允许权限
 *
 *  * 必须申请的权限
 *
 *  * android.permission.READ_PHONE_STATE
 *  * android.permission.WRITE_EXTERNAL_STORAGE
 *
 *
 *  * 可选申请的权限
 *
 *  * android.permission.ACCESS_FINE_LOCATION
 *
 *
 *
 * Android 6.0+ 权限申请助手

 * @since 2016-01-12
 */
class PermissionHelper(private val mActivity: Activity) {

    /**
     * 有米 Android SDK 所需要向用户申请的权限列表
     */
    private val mPermissionModels = arrayOf(PermissionModel("电话", Manifest.permission.READ_PHONE_STATE, "我们需要读取手机信息的权限来标识您的身份", READ_PHONE_STATE_CODE), PermissionModel(
            "存储空间",
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            "我们需要您允许我们读写你的存储卡，以方便我们临时保存一些数据",
            WRITE_EXTERNAL_STORAGE_CODE
    ))

    private var mOnApplyPermissionListener: OnApplyPermissionListener? = null

    fun setOnApplyPermissionListener(onApplyPermissionListener: OnApplyPermissionListener) {
        mOnApplyPermissionListener = onApplyPermissionListener
    }

    /**
     * 这里我们演示如何在Android 6.0+上运行时申请权限
     */
    fun applyPermissions() {
        try {
            for (model in mPermissionModels) {
                if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(mActivity, model.permission!!)) {
                    ActivityCompat.requestPermissions(mActivity, arrayOf<String>(model.permission!!), model.requestCode)
                    return
                }
            }
            if (mOnApplyPermissionListener != null) {
                mOnApplyPermissionListener!!.onAfterApplyAllPermission()
            }
        } catch (e: Throwable) {
            Log.e(TAG, "", e)
        }

    }

    /**
     * 对应Activity的 `onRequestPermissionsResult(...)` 方法

     * @param requestCode
     * *
     * @param permissions
     * *
     * @param grantResults
     */
    fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        when (requestCode) {
            READ_PHONE_STATE_CODE, WRITE_EXTERNAL_STORAGE_CODE -> {
                // 如果用户不允许，我们视情况发起二次请求或者引导用户到应用页面手动打开
                if (PackageManager.PERMISSION_GRANTED != grantResults[0]) {

                    // 二次请求，表现为：以前请求过这个权限，但是用户拒接了
                    // 在二次请求的时候，会有一个“不再提示的”checkbox
                    // 因此这里需要给用户解释一下我们为什么需要这个权限，否则用户可能会永久不在激活这个申请
                    // 方便用户理解我们为什么需要这个权限
                    if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, permissions[0])) {
                        val builder = AlertDialog.Builder(mActivity).setTitle("权限申请")
                                .setMessage(findPermissionExplain(permissions[0])).setPositiveButton(
                                "确定"
                        ) { dialog, which -> applyPermissions() }
                        builder.setCancelable(false)
                        builder.show()
                    } else {
                        val builder = AlertDialog.Builder(mActivity).setTitle("权限申请")
                                .setMessage("请在打开的窗口的权限中开启" +
                                        findPermissionName(permissions[0]) +
                                        "权限，以正常使用本应用")
                                .setPositiveButton(
                                        "去设置"
                                ) { dialog, which ->
                                    openApplicationSettings(
                                            REQUEST_OPEN_APPLICATION_SETTINGS_CODE)
                                }
                                .setNegativeButton(
                                        "取消"
                                ) { dialog, which -> mActivity.finish() }
                        builder.setCancelable(false)
                        builder.show()
                    }// 到这里就表示已经是第3+次请求，而且此时用户已经永久拒绝了，这个时候，我们引导用户到应用权限页面，让用户自己手动打开
                    return
                }

                // 到这里就表示用户允许了本次请求，我们继续检查是否还有待申请的权限没有申请
                if (isAllRequestedPermissionGranted) {
                    if (mOnApplyPermissionListener != null) {
                        mOnApplyPermissionListener!!.onAfterApplyAllPermission()
                    }
                } else {
                    applyPermissions()
                }
            }
        }
    }

    /**
     * 对应Activity的 `onActivityResult(...)` 方法

     * @param requestCode
     * *
     * @param resultCode
     * *
     * @param data
     */
    fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
        when (requestCode) {
            REQUEST_OPEN_APPLICATION_SETTINGS_CODE -> if (isAllRequestedPermissionGranted) {
                if (mOnApplyPermissionListener != null) {
                    mOnApplyPermissionListener!!.onAfterApplyAllPermission()
                }
            } else {
                mActivity.finish()
            }
        }
    }

    /**
     * 判断是否所有的权限都被授权了

     * @return
     */
    val isAllRequestedPermissionGranted: Boolean
        get() {
            for (model in mPermissionModels) {
                if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(mActivity, model.permission!!)) {
                    return false
                }
            }
            return true
        }

    /**
     * 打开应用设置界面

     * @param requestCode 请求码
     * *
     * @return
     */
    private fun openApplicationSettings(requestCode: Int): Boolean {
        try {
            val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + mActivity.packageName))
            intent.addCategory(Intent.CATEGORY_DEFAULT)

            // Android L 之后Activity的启动模式发生了一些变化
            // 如果用了下面的 Intent.FLAG_ACTIVITY_NEW_TASK ，并且是 startActivityForResult
            // 那么会在打开新的activity的时候就会立即回调 onActivityResult
            // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mActivity.startActivityForResult(intent, requestCode)
            return true
        } catch (e: Throwable) {
            Log.e(TAG, "", e)
        }

        return false
    }

    /**
     * 查找申请权限的解释短语

     * @param permission 权限
     * *
     * @return
     */
    private fun findPermissionExplain(permission: String): String? {
        if (mPermissionModels != null) {
            for (model in mPermissionModels) {
                if (model != null && model.permission != null && model.permission == permission) {
                    return model.explain
                }
            }
        }
        return null
    }

    /**
     * 查找申请权限的名称

     * @param permission 权限
     * *
     * @return
     */
    private fun findPermissionName(permission: String): String? {
        if (mPermissionModels != null) {
            for (model in mPermissionModels) {
                if (model != null && model.permission != null && model.permission == permission) {
                    return model.name
                }
            }
        }
        return null
    }

    private class PermissionModel(
            /**
             * 权限名称
             */
            var name: String,
            /**
             * 请求的权限
             */
            var permission: String?,
            /**
             * 解析为什么请求这个权限
             */
            var explain: String,
            /**
             * 请求代码
             */
            var requestCode: Int)

    /**
     * 权限申请事件监听
     */
    interface OnApplyPermissionListener {

        /**
         * 申请所有权限之后的逻辑
         */
        fun onAfterApplyAllPermission()
    }

    companion object {

        private val TAG = "PermissionHelper"

        /**
         * 小tips:这里的int数值不能太大，否则不会弹出请求权限提示，测试的时候,改到1000就不会弹出请求了
         */
        private val READ_PHONE_STATE_CODE = 101

        private val WRITE_EXTERNAL_STORAGE_CODE = 102

        private val REQUEST_OPEN_APPLICATION_SETTINGS_CODE = 12345
    }

}
